#! /usr/bin/php
<?php
ini_set('date.timezone', 'Asia/Shanghai');
define('DS', DIRECTORY_SEPARATOR);
function disp($text, $color = false, $indentSize = 0, $newline = 1) {
  $colors = array(
    'black' => 30,
    'red' => 31,
    'green' => 32,
    'yellow' => 33,
    'blue' => 34,
    'magenta' => 35,
    'cyan' => 36,
    'gray' => 37
  );
  if ($indentSize > 0) {
    echo str_repeat(" ", $indentSize);
  }
  if (DS == "\\"
    || $color == false
    || !isset($colors[$color])) {     // Windows
    echo $text;
  } else {    // Linux & macOS
    echo "\033[" . $colors[$color] . "m" . $text . "\033[0m";
  }
  if ($newline > 0) {
    echo str_repeat("\n", $newline);
  }
}

$flag = true;

function compare_files($array, $path) {
    global $flag;
    foreach ($array as $key => $value) {
        if (is_array($value)) {
            compare_files($value, $path . $key . '/');
        } else {
            $filepath = $path . $key;
            if (!file_exists($filepath)) {
                $flag = -1;
                disp("[important] File `${key}` is defined in checklist but not found in `${path}`.", 'red');
                continue;
            }
            $checksum = md5(file_get_contents($filepath));
            if ($checksum != $value) {
                $flag = 0;
                disp("[warning] Checksum of `${key}` is ${checksum} but the correct checksum should be `${value}`. The file may be damaged.", 'magenta');
            }
        }
    }
}

disp("-----------------------------------------------------------");
?>
        ██╗  ██╗ █████╗ ███████╗███████╗███████╗
        ██║  ██║██╔══██╗██╔════╝██╔════╝██╔════╝
        ███████║███████║███████╗█████╗  █████╗  
        ██╔══██║██╔══██║╚════██║██╔══╝  ██╔══╝  
        ██║  ██║██║  ██║███████║███████╗███████╗
        ╚═╝  ╚═╝╚═╝  ╚═╝╚══════╝╚══════╝╚══════╝
                                        
<?php 
disp("       Hasee Tongfang EFI troubleshooting script    ", 'green', 0, 2);
disp("            神舟同方机型 EFI 文件故障自助排查工具        ", 'green', 0, 2);
disp("    @Copyright 2019 Yume Maruyama<kirainmoe@gmail.com>", "blue", 0, 2);
disp("     https://github.com/kirainmoe/hasee-tongfang-macos ");
disp("-----------------------------------------------------------");

/* Read info.json from current EFI... */
$jsonPath = dirname(__FILE__) . DS . "info.json";
if (!file_exists($jsonPath)) {
    disp("[error] 找不到 info.json，排错程序无法运行！请尝试重新下载或替换配置文件.", "red", 0);
    exit(0);
}
$info = json_decode(file_get_contents($jsonPath), true);
usleep(500000);


disp("[info] 当前机型是 " . $info['model'] .  " 系列。正在初始化问题诊断工具...", "cyan");

/* Check current system version */
disp("[info] 正在检测系统版本...", "cyan", 0);
exec("sw_vers 2>&1", $res);
preg_match("/(10\.1.*)/", $res[1], $match);

if (!in_array($match[1], $info['supported_macos_version'])) {
    disp("[error] 当前 macOS 版本为 ${match[1]}，配置文件支持的版本为：", "red", 0);
    for ($i = 0; $i < count($info['supported_macos_version']); $i++) 
        disp($info['supported_macos_version'][$i], 'black', 2);
} else {
    disp("[ok] 当前下载的配置文件支持当前系统版本： ${match[1]}", 'green');
    disp("[ok] 当前配置文件版本：${info['build']}，构建时间戳是 ${info['timestamp']}", "green");
}
usleep(500000);

/* Check if system using kirainmoe's EFI */
$res = array();
disp('[info] 正在检测当前系统是否使用 aya\'s EFI 启动...', 'cyan');
exec("ioreg -l | grep YMR2 2>&1", $res);

if (empty($res)) {
    disp("[error] 检测到当前系统使用的配置文件是第三方配置文件。我们无法帮您诊断问题。", "red");
    disp("[error] 请检查您的 EFI 配置文件是否替换正确，修复后请重新启动系统。", "red");
    exit(0);
} else {
    disp("[ok] 当前系统正在使用 aya's EFI.", 'green');    
}

disp('[info] 正在检测声卡是否正常……', 'cyan');
exec("kextstat | grep AppleALC", $res);

if (empty($res)) {
    disp("[error] AppleALC 驱动没有正确加载。请检查 Lilu 和 AppleALC 是否存在。如果您运行较新版本的系统，需要使用 -alcbeta 参数启动。", "red");
} else {
    exec("ioreg -l | grep alc-layout-id", $res);
    if (empty($res)) {
        disp("[error] alc-layout-id 没有被正确注入，声音输入输出设备可能无法正常工作。", "red");
    } else {
        disp("[ok] 声卡驱动工作正常。", "green");
    }
}
usleep(500000);


if ($info['model'] != 'KP7/5GC') {
    disp('[info] 正在检测触摸板是否正常……', 'cyan');
    exec("kextstat | grep VoodooI2CHID", $res);

    if (empty($res)) {
        disp("[error] I2C 触摸板驱动没有正确加载，将尝试自动修复...", "red");
        usleep(500000);
        disp("[info] 即将执行重建缓存操作，请在下面输入您的系统密码：", 'cyan');
        exec("sudo kextcache -i /", $res);
        disp("[info] 请尝试重新启动电脑。", "cyan");
    }
}
usleep(500000);

disp("[info] 开始比较文件，这可能需要一些时间...", "cyan");
$basedir = dirname(dirname(__FILE__)) . '/';
compare_files($info['hash'], $basedir);

if ($flag == 1) {
    disp("[ok] 文件完整性校验通过。", "green");
} else if ($flag == -1) {
    disp("[error] 文件完整性校验失败，未通过校验的文件已列出，这些文件可能已经丢失或损坏。请尝试手动修复这些文件。", 'red');
    exit(0);
} else {
    disp("[warning] 文件完整性校验失败，未通过校验的文件已列出，如果其中有一些文件是您手动修改过的，请忽略它们。这些文件可能已经损坏。请尝试手动修复这些文件。", 'magenta');
}
usleep(500000);

disp("[info] 正在检测远程分支版本...", "cyan", 0);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://raw.githubusercontent.com/kirainmoe/hasee-tongfang-macos/' . $info['branch'] .  '/Addons/info.json');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$res = curl_exec($ch);
curl_close($ch);

if (empty($res)) {
    disp("[error] 检测远程分支版本失败，可能原因是网络状况较差。请您手动检查是否有新版本或为终端设置代理服务器后重试。", 'red');
    exit(0);
} else {
    $remote = json_decode($res, true);

    if ($info['build'] < $remote['build'] || $info['timestamp'] < $remote['timestamp']) {
        disp("[tips] 您使用的配置文件版本不是最新。您当前的版本是：Build ${info['build']}, ${info['timestamp']}; 远程版本是：Build ${remote['build']}, ${remote['timestamp']}", 'magenta');
        disp("[tips] 请考虑更新配置文件到最新版本，更新地址：https://github.com/kirainmoe/hasee-tongfang-macos/releases", 'magenta');
    } else {
        disp("[ok] 您使用的是最新的配置文件。您当前的版本是：Build ${info['build']}, ${info['timestamp']}.", 'green');
        usleep(500000);

        if ($info['build'] == $remote['build'] && $info['timestamp'] == $remote['timestamp']) {
            disp("[info] 正在与远程文件进行比较...", 'cyan');

            $remoteFile = file_get_contents('https://raw.githubusercontent.com/kirainmoe/hasee-tongfang-macos/' . $info['branch'] .  '/Addons/info.json');
            $remoteJson = json_decode($remoteFile, true);
    
            $flag = 1;
            compare_files($remoteJson['hash'], $basedir);
    
            if ($flag == 1) {
                disp("[ok] 当前配置文件与远程分支保持一致，校验通过。", "green");
            } else {
                disp("[error] 本地完整性校验通过，但在与远程文件比较时发现文件不一致。请尝试手动修复不同的文件。", 'red');
            }
        }
    }
}

disp("[done] 排错程序运行完成。如果上面显示了错误信息，请您根据提示排错。如果仍然无法解决您的问题，请在 GitHub 提 issues.");
